package ConveyorBelt.Actors;

import org.newdawn.slick.Animation;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
import org.newdawn.slick.geom.Shape;
import org.newdawn.slick.geom.Vector2f;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.util.pathfinding.Path;
import org.newdawn.slick.util.pathfinding.Path.Step;

import ConveyorBelt.Base.Body;
import ConveyorBelt.Base.Entity;
import ConveyorBelt.Base.Level;
import ConveyorBelt.Base.Score;
import ConveyorBelt.Brain.DummyBrain;
import ConveyorBelt.Map.Map;
import ConveyorBelt.Util.Collider;
import ConveyorBelt.Util.SheetUtil;

public class Dummy extends Body {
	public Map map;
	public SpriteSheet sheet;
	public boolean toRemove;
	public String lastDir;
	public Animation sprite, up, down, left, right;
	public static final float SPEED = 0.09f;
	public Path path = null;
	public DummyBrain brain;
	public Color color;
	
	public Dummy(Map parent, Role role, Shape shape, DummyBrain brain, Color color) throws SlickException {
		super(role, shape);
		map = parent;
		this.brain = brain;
		this.color = color;
		init();
	}
	
	public void init() {
		lastDir = "down";
		try {
			if(color == Color.blue) sheet = new SpriteSheet("map/dummy1.png", 32, 32);
			else if(color == Color.yellow) sheet = new SpriteSheet("map/dummy2.png" ,32, 32);
			else if(color == Color.red) sheet = new SpriteSheet("map/dummy3.png" ,32, 32);
			else if(color == Color.green) sheet = new SpriteSheet("map/dummy4.png" ,32, 32);
		} catch (Exception e) {
			System.out.println("Cant find sprite sheet path");
		}
		up = SheetUtil.getAnimationFromSheet(sheet, 5, 0, 7);
		down = SheetUtil.getAnimationFromSheet(sheet, 4, 0, 7);
		left = SheetUtil.getAnimationFromSheet(sheet, 7, 0, 7);
		right = SheetUtil.getAnimationFromSheet(sheet, 6, 0, 7);
		sprite = down;
	}
	
	@Override
	public void render(BasicGameState bgs, Graphics g) {
		sprite.draw(getX(), getY());
	}

	@Override
	public void update(GameContainer gc, int delta) {
		Collider.checkColliding(this, Map.destinationEntities);
		brain.update(gc,delta);
		doMovement(brain.getCurrentStep(), delta);
	}
	
	public void doMovement(Step step, int delta) {
		float sx = getX();
	    float sy = getY();
	    float tx = step.getX()*32 + map.mapX;
	    float ty = step.getY()*32 + map.mapY;
    	float dx = sx - tx;
	    float dy = sy - ty;
	    
	    if (Math.abs(dx) < 1 && Math.abs(dy) < 1) {
	    	shape.setX(tx);
	    	shape.setY(ty);
	    	brain.goToNextStep(getPosition());
	    } else {
			boolean moveRight = false;
			boolean moveLeft = false;
			boolean moveUp = false;
			boolean moveDown = false;

			if (dx < 0) moveRight = true;
			else if (dx > 0) moveLeft = true;	
			else if (dy < 0) moveDown = true;
			else if (dy > 0) moveUp = true;
				
			if (moveUp) {
				sprite = up;
			    sprite.update(delta);
			    float y = getY() - delta * SPEED;
			    shape.setY(y);
			    lastDir = "up";
			} else if (moveDown) {
				sprite = down;
				sprite.update(delta);
				float y = getY() + delta * SPEED;
				shape.setY(y);
				lastDir = "down";
		    } else if (moveLeft) {
			    sprite = left;
			    sprite.update(delta);
			    float x = getX() - delta * SPEED;
			    shape.setX(x);
			    lastDir = "left";
			} else if (moveRight) {
				sprite = right;
				sprite.update(delta);
				float x = getX() + delta * SPEED;
				shape.setX(x);
				lastDir = "right";
		    }
		}
	}
	public Color getColor() {
		return color;
	}
	
	@Override
	public Role getRole() {
		return Role.DUMMY;
	}

	@Override
	public void addToLevel(Level l) {
		l.add(this);
	}

	@Override
	public void removeFromLevel(Level l) {
		l.remove(this);
	}

	@Override
	public void onCollision(Entity obstacle) {
		if(obstacle.getRole() == Role.DESTINATION) {
			Destination des = (Destination) obstacle;
			toRemove = true;		
			if(color.equals(des.getColor())) {
				if(des.toRemove) {
					Score.setCurrentScore(-20);
					try {
						Shape startPosition = this.map.getStartPosition("start_position");
						DummyBrain newBrain = new DummyBrain(this.map, new Vector2f(startPosition.getX(), startPosition.getY()));
						Map.addToDummyQueue(new Dummy(this.map, Role.DUMMY, startPosition, newBrain, this.color));
					} catch (SlickException e) {
						e.printStackTrace();
					}
				}
				else Score.setCurrentScore(50);
			}
			else {
				if(des.toRemove) {
					Score.setCurrentScore(-40);
					try {
						Shape startPosition = this.map.getStartPosition("start_position");
						DummyBrain newBrain = new DummyBrain(this.map, new Vector2f(startPosition.getX(), startPosition.getY()));
						Map.addToDummyQueue(new Dummy(this.map, Role.DUMMY, startPosition, newBrain, this.color));
					} catch (SlickException e) {
						e.printStackTrace();
					}
				}
				else { 
					Score.setCurrentScore(-20);
					try {
						Shape startPosition = this.map.getStartPosition("start_position");
						DummyBrain newBrain = new DummyBrain(this.map, new Vector2f(startPosition.getX(), startPosition.getY()));
						Map.addToDummyQueue(new Dummy(this.map, Role.DUMMY, startPosition, newBrain, this.color));
					} catch (SlickException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	@Override
	public boolean isToRemove() {
		return toRemove;
	}
	
}
